﻿using System.ComponentModel;
using Engine;
using Engine.Cameras;
using EngineDrawer.Objects.StaticObjects;
using EngineDrawer.Sky;
using EngineDrawer.Terrain;
using System.Linq;
using Microsoft.Xna.Framework;

namespace EngineDrawer
{
    public class WorldDrawer:DrawableGameComponent
    {        
        #region Fields

        private readonly string WorldMapPath;
        private BaseCamera _camera;

        #endregion  

        #region Properties

        private World _world;
        public World World
        {
            get { return _world; }
            set 
            { 
                _world = value;
                Game.Services.RemoveService(typeof(World));
                _world.PropertyChanged += OnWorldPropertyChanged;
                Game.Services.AddService(typeof(World), _world);
            }
        }

        #endregion

        #region Constructors

        public WorldDrawer(Game game,string worldMapPath):base(game)
        {
            WorldMapPath = worldMapPath;
        }

        #endregion

        #region Override

        public override void Initialize()
        {
            _camera = (BaseCamera) Game.Services.GetService(typeof (BaseCamera));                    
            Game.Services.AddService(typeof(WorldDrawer),this);
            InitWorld();            
            InitTerrainDrawer();
            InitStaticObjects();            
            base.Initialize();
        }
        private void InitWorld()
        {
            if (!string.IsNullOrEmpty(WorldMapPath))
            {
                IWorldLoader worldLoader = (IWorldLoader) Game.Services.GetService(typeof (IWorldLoader));
                World = worldLoader.Load(Game, WorldMapPath);
            }
            else
            {
                World = CreateWorldObject();
                World.LoadTerrain("default_terrain.map");
            }
        }
        public override void Update(GameTime gameTime)
        {
            World.ViewMatrix = _camera.ViewMatrix;
            base.Update(gameTime);
        }

        #endregion

        #region Private Methods

        virtual protected World CreateWorldObject()
        {
            return new World(Game);
        }
        private void InitStaticObjects()
        {
            StaticObjectDrawer drawer=new StaticObjectDrawer(Game);
            Game.Components.Add(drawer);
        }
        private void InitTerrainDrawer()
        {
            TerrainDrawer terrainDrawer = new TerrainDrawer(Game);           
            Game.Components.Add(terrainDrawer);   
        }
        private void RemvoeSkydome()
        {
            var skyDomeComponent = Game.Components.Where(c => c is SkyDomeDrawer).FirstOrDefault();
            Game.Components.Remove(skyDomeComponent);
        }
        private void InitSkydome()
        {
            SkyDomeDrawer drawer=new SkyDomeDrawer(Game,"Objects\\skydome","Textures\\skydome");
            Game.Components.Add(drawer);
        }

        #endregion
        

        #region Events

        virtual protected void OnWorldPropertyChanged(object sender,PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "DrawSky")
                OnDrawSkyPropertyChanged();

            
        }
        virtual protected void OnDrawSkyPropertyChanged()
        {
            if(World.DrawSky)   
                InitSkydome();
            else
                RemvoeSkydome();
        }
        #endregion
    }
}
